#include "CRCWorker.h"

namespace miniprojeto {
namespace Redundancy {

void CRCWorker::run() {
	BitStream* bitStream = new BitStream (block->getBytes(), CRCBlocks::BLOCK_SIZE + 2);
	Bits32Sequence* bitsReads = new Bits32Sequence(0x0);
	Bits32Sequence* reminder = new Bits32Sequence(0x0);
	bool end = false;
	int reads = bitStream->getNbits(reminder, 17);
	int ite = 0;
	while (!end) {
		ite++;
		int nZeros = countZeros(reminder);
		reads = nZeros;

		if (nZeros != 0) {
			reads = bitStream->getNbits(bitsReads, nZeros);
			reminder->deslocLeft(reads);
			reminder->binaryOr(bitsReads);
		}
		if (reads != nZeros) {
			end = true;
			block->setReminder((unsigned short) reminder->getSequence());
			
		} else {
			reminder->binaryXor(CRC);
		}
	}
	finishListener->recevFinishWorkNotification((void *) this);
	delete bitsReads;
	delete reminder;
	delete bitStream;
}

void CRCWorker::setCRCBlock(CRCBlocks* nBlock) {
	this->block = nBlock;
}

void CRCWorker::addFinishListener(CRCFinishListener* listener) {
	this->finishListener = listener;
}

void CRCWorker::setNumber(int n) {
	this->number = n;
	block->setNumber(n);
}

CRCWorker::CRCWorker() : Thread() {
	
}

CRCWorker::~CRCWorker() {
	//~Thread();
}

CRCBlocks* CRCWorker::getCRCBlocks() {
	return this->block;
}

int CRCWorker::countZeros(Bits32Sequence* seq) {
	int count = 0;
	for (int i = 16; i >= 0; i--) {
		if (seq->isBitN(i, ZERO)) {
			count++;	
		} else {
			return count;
		}
	}
	return count;
}

Bits32Sequence* CRCWorker::CRC = new Bits32Sequence(0x00018005);

}
}
